package com.gitee.cliveyuan.tools.http;

import com.gitee.cliveyuan.tools.CollectionTools;
import com.gitee.cliveyuan.tools.cons.NetCons;
import com.gitee.cliveyuan.tools.exception.NetException;
import org.jsoup.Connection;
import org.jsoup.HttpStatusException;
import org.jsoup.Jsoup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

/**
 * jsoup 工具
 * <p>
 * Created by Clive at 2018/07/24.
 * Rebuilt by Clive at 2018/11/26.
 *
 * @since 2.0.0
 */
public class JsoupTools extends AbstractHttpRequest {

    private static final Logger logger = LoggerFactory.getLogger(JsoupTools.class);

    private JsoupTools() {
        timeout = NetCons.JSOUP_TIME_OUT;
    }

    // region public methods

    /**
     * 构建jsoup工具
     *
     */
    public static JsoupTools build() {
        return new JsoupTools();
    }

    @Override
    public String get() throws NetException {
        url = InnerTools.getQueryUrl(url, params);
        return request(Connection.Method.GET).getContent();
    }

    @Override
    public String post() throws NetException {
        return request(Connection.Method.POST).getContent();
    }

    @Override
    public HttpResp executeGet() throws NetException {
        return request(Connection.Method.GET);
    }

    @Override
    public HttpResp executePost() throws NetException {
        return request(Connection.Method.POST);
    }
    // endregion public methods


    // region private methods

    private HttpResp request(
            Connection.Method method
    ) throws NetException {
        try {
            Connection connection = getConnection()
                    .method(method);
            if (CollectionTools.isNotEmpty(headers)) {
                headers.forEach(connection::header);
            }
            if (CollectionTools.isNotEmpty(cookies)) {
                connection.cookies(cookies);
            }
            if (CollectionTools.isNotEmpty(params)) {
                connection.data(params);
            }
            Connection.Response execute = connection.execute();
            return HttpResp.create(execute.body(), execute.cookies(), execute.headers());
        } catch (UnknownHostException e) {
            throw NetException.unknownHost();
        } catch (HttpStatusException e) {
            logger.info("http status error: statusCode={}, url={}", e.getStatusCode(), e.getUrl());
            throw NetException.httpStatusError(e.getStatusCode());
        } catch (SocketTimeoutException e) {
            throw NetException.timeout(timeout);
        } catch (ConnectException e) {
            throw NetException.connectionRefused(url);
        } catch (Exception e) {
            //e.printStackTrace();
            logger.error("request error", e);
            throw NetException.unKnowError();
        }

    }

    private Connection getConnection() {
        Connection connection = Jsoup.connect(url)
                .ignoreContentType(true)
                .timeout(timeout);
        if (addDefaultHeaders)
            NetCons.DEFAULT_HEADERS.forEach(connection::header);
        return connection;
    }

    // endregion private methods


}
